package cn.tedu.tmall.admin.mall.service.impl;

import cn.tedu.tmall.admin.mall.dao.repository.IMallCategoryRepository;
import cn.tedu.tmall.admin.mall.pojo.po.MallCategoryPO;
import cn.tedu.tmall.admin.mall.pojo.pram.MallCategoryAddParam;
import cn.tedu.tmall.admin.mall.pojo.vo.MallCategoryTreeVO;
import cn.tedu.tmall.admin.mall.pojo.vo.MallCategoryVO;
import cn.tedu.tmall.admin.mall.service.IMallCategoryService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class MallCategoryService implements IMallCategoryService {
    @Autowired
    private IMallCategoryRepository mallCategoryRepository;
    @Override
    public void add( MallCategoryAddParam mallCategoryAddParam) {
        //类别名称不能重复
        String name = mallCategoryAddParam.getName();
        Long count = mallCategoryRepository.countCategoryByName(name);
        if (count != 0L) {
            throw new RuntimeException("类别已经存在");
        } else {
            //判断类别是子类还是父类
            Long parentId = mallCategoryAddParam.getParentId();
            if (parentId == 0) {
                //父类直接添加,不用计算深度
                MallCategoryPO mallCategoryPO = new MallCategoryPO();
                BeanUtils.copyProperties(mallCategoryAddParam, mallCategoryPO);
                mallCategoryPO.setDepth(1);
                mallCategoryPO.setParentId(0L);
                mallCategoryRepository.save(mallCategoryPO);
            } else {
                //子类
                //判断父类是否存在
                //需要想一想是否还要后续操作
                //判断父类是否存在
                MallCategoryPO parentMallCategoryPO = mallCategoryRepository.getCategoryById(mallCategoryAddParam.getParentId());
                if (parentMallCategoryPO == null) {
                    throw new RuntimeException("父类不存在");
                } else {
                    //判断是否启用
                    Integer enable = parentMallCategoryPO.getEnable();
                    if (enable == 0) {
                        throw new RuntimeException("父级类别没有启用");
                    } else {
                        //计算深度,存数据
                        Integer depth = parentMallCategoryPO.getDepth();
                        MallCategoryPO chilrdMallCategoryPO = new MallCategoryPO();
                        BeanUtils.copyProperties(mallCategoryAddParam, chilrdMallCategoryPO);
                        chilrdMallCategoryPO.setDepth(depth + 1);
                        chilrdMallCategoryPO.setIsParent(0);
                        //保存子类
                        mallCategoryRepository.save(chilrdMallCategoryPO);
                        //需要处理多次保存同一父级下的子级,会多次更新
                        if(parentMallCategoryPO.getParentId()!=1) {
                            //保存父类的isParent=1
                            MallCategoryPO update = new MallCategoryPO();
                            update.setId(parentId);
                            update.setIsParent(1);
                            mallCategoryRepository.updateCategoryById(update);
                        }

                    }
                }
            }
        }
    }
    @Override
    public List<MallCategoryVO> topCategory() {
        return  topCategory(0L);
    }

    @Override
    public List<MallCategoryVO> topCategory(Long parentId) {
        List<MallCategoryPO> categoryPOS = mallCategoryRepository.listCategoryByPrentId(parentId);
        List<MallCategoryVO> mallCategoryVOS = new ArrayList<>();
        //需要返回的VO
        for (MallCategoryPO categoryPO : categoryPOS) {
            MallCategoryVO mallCategoryVO = new MallCategoryVO();
            BeanUtils.copyProperties(categoryPO, mallCategoryVO);
            mallCategoryVOS.add(mallCategoryVO);
        }
        return mallCategoryVOS;
    }

    /**
     *  1. 先取出全部数据
     *  2. 取出parentId == 0 的数据 并通过categoryPO2VO转化为vo
     *  3. 取出孩子
     */

    @Override
    public List<MallCategoryTreeVO> getAll() {
        //先取出全部数据
        List<MallCategoryPO> mallCategoryPOS = mallCategoryRepository.getAll();

        //取出parentId == 0 的数据
        List <MallCategoryTreeVO> topMallCategoryTreeVOS = new ArrayList<>();
        for (MallCategoryPO mallCategoryPO : mallCategoryPOS) {
            if (mallCategoryPO.getParentId()==0) {
                MallCategoryTreeVO mallCategoryTreeVO = categoryPO2VO(mallCategoryPO);
                topMallCategoryTreeVOS.add(mallCategoryTreeVO);
            }
        }
        //开始取出第二层数据
        for (MallCategoryTreeVO topMallCategoryTreeVO : topMallCategoryTreeVOS) {
                appendChild(topMallCategoryTreeVO,mallCategoryPOS);
        }

        return topMallCategoryTreeVOS;
    }

    private MallCategoryTreeVO  appendChild(MallCategoryTreeVO topMallCategoryTreeVO,List<MallCategoryPO> mallCategoryPOS) {
        List <MallCategoryTreeVO> childMallCategoryTreeVOS = new ArrayList<>();
        for (MallCategoryPO mallCategoryPO : mallCategoryPOS) {
            //取出子类
            if(topMallCategoryTreeVO.getId()==mallCategoryPO.getParentId()) {
                MallCategoryTreeVO chiderMallCategoryTreeVO = categoryPO2VO(mallCategoryPO);
                //顶数据不变,只是一直在深挖
//                对象引用特性：chiderMallCategoryTreeVO 是一个对象，当你调用 appendChild 时，方法内部会修改该对象的 children 属性（添加子节点）。由于 Java 中对象传递的是引用，后续将该对象添加到 childMallCategoryTreeVOS 集合中时，集合中存储的是同一个对象引用，因此 appendChild 对对象的修改会同步反映到集合中的对象上。
//                逻辑等价性：
//                先调用 appendChild 再添加到集合：修改对象后存入集合，集合中的对象已包含子节点。
//                先添加到集合再调用 appendChild：对象存入集合后，appendChild 仍能通过引用修改集合中对象的 children 属性。
                appendChild(chiderMallCategoryTreeVO,mallCategoryPOS);
                childMallCategoryTreeVOS.add(chiderMallCategoryTreeVO);

                //childMallCategoryTreeVOS.add(appendChild(chiderMallCategoryTreeVO,mallCategoryPOS));
                //接着循环孙子列表在这里
            }else {

            }
        }
        topMallCategoryTreeVO.setChildren(childMallCategoryTreeVOS);
        return topMallCategoryTreeVO;
    }
    private MallCategoryTreeVO categoryPO2VO(MallCategoryPO mallCategoryPO)  {
        MallCategoryTreeVO mallCategoryTreeVO = new MallCategoryTreeVO();
        BeanUtils.copyProperties(mallCategoryPO,mallCategoryTreeVO);
        return mallCategoryTreeVO;
    }
}
